| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157 |
- import clsx from "clsx";
- import Link from "next/link";
- import { useContext, useMemo } from "react";
- import { useRouter } from "next/router";
- import { GetServerSideProps } from "next";
- import { get } from "libs/http";
- import useGet from "libs/hooks/useGet";
- import { Context } from "libs/context";
- import NovelItem from "components/NovelItem";
- import styles from "styles/genre.module.scss";
- import useStore from "libs/hooks/useStore";
- import { SeoHead, SeoHeadConfig } from "components/SeoHead";
- const Genre = () => {
- const { query } = useRouter();
- const { siteConfig } = useStore();
- const { data } = useGet<ListItem[]>(
- query.genre ? `/api/genre/${query.genre}` : "/api/list"
- );
- const store = useContext(Context);
- const currentName = useMemo(() => {
- const item = store.genre.find((item) => item.uri === query.genre);
- return item ? item.name : "All";
- }, [query.genre, store.genre]);
- const seoConfig: SeoHeadConfig = useMemo(() => {
- // const genreName =
- return {
- title: `${currentName} Novels - ${siteConfig.siteName}`,
- description: `Explore ${currentName} Web Novels on NovelDit. Online Reading ${currentName} Web Novels for Free!`,
- keywords: `${[
- `${currentName} stories`,
- `${currentName} novels`,
- `read ${currentName} novels`,
- siteConfig.keywords,
- siteConfig.siteName,
- ].join(", ")}`,
- url: `https://${siteConfig.host}/novels${
- query.genre ? `/${query.genre}` : ""
- }`,
- jsonLd: JSON.stringify([
- {
- "@context": "https://schema.org",
- "@type": "BreadcrumbList",
- itemListElement: [
- {
- "@type": "ListItem",
- position: 1,
- name: "Home",
- item: `https://${siteConfig.host}`,
- },
- {
- "@type": "ListItem",
- position: 2,
- name: "All Novels",
- item: `https://${siteConfig.host}/novels`,
- },
- ...(query.genre
- ? [
- {
- "@type": "ListItem",
- position: 3,
- name: `${currentName} Novels`,
- item: `https://${siteConfig.host}/novels/${query.genre}`,
- },
- ]
- : []),
- ],
- },
- {
- "@context": "https://schema.org",
- "@type": "ItemList",
- itemListElement: (data?.data || []).map((item, idx) => ({
- "@type": "ListItem",
- position: idx + 1,
- url: `https://${siteConfig.host}/novel/${item.uri}`,
- name: item.name,
- image:
- "http://img.webnovel.com/bookcover/16709365405930105/600/600.jpg",
- author: { "@type": "Person", name: item.author },
- publisher: { "@type": "Organization", name: siteConfig.siteName },
- })),
- },
- ...siteConfig.jsonLd,
- ]),
- };
- }, [
- currentName,
- data?.data,
- query.genre,
- siteConfig.host,
- siteConfig.jsonLd,
- siteConfig.keywords,
- siteConfig.siteName,
- ]);
- return (
- <main className="container">
- <SeoHead seoConfig={seoConfig} />
- <h2 className="novel-title">Genres</h2>
- <div className={styles.genres}>
- <Link
- href="/novels"
- title="All novels"
- className={clsx(styles.genre, {
- [styles.current]: !query.genre,
- })}
- >
- All
- </Link>
- {store.genre.map((item) => (
- <Link
- href={`/novels/${item.uri}`}
- key={item.uri}
- title={item.name}
- className={clsx(styles.genre, {
- [styles.current]: query.genre === item.uri,
- })}
- >
- {item.name}
- </Link>
- ))}
- </div>
- <h2 className="novel-title">{`${currentName} Novels`}</h2>
- <ul className="novel-list">
- {(data?.data || []).map((item) => (
- <NovelItem
- key={item.uri}
- slug={item.uri}
- img={item.img}
- name={item.name}
- />
- ))}
- </ul>
- </main>
- );
- };
- export const getServerSideProps: GetServerSideProps<
- { fallback: Docs },
- { genre: string }
- > = async ({ params }) => {
- const key = params?.genre ? `/api/genre/${params.genre}` : `/api/list`;
- const data = await get(key);
- return {
- props: {
- fallback: {
- [key]: data,
- },
- },
- };
- };
- export default Genre;
|